package com.itheima;

import com.itheima.service.MyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/*
* 我们使用这个代码，发现foo()方法并没有被增强，原因是因为我们这里并没有使用aspectj的编译器
* 所以就没有得到增强；但是我们可以通过agent的方式来实现增强，我们需要在运行代码时，加上一个
* jvm参数：-javaagent:C:/Users/manyh/.m2/repository/org/aspectj/aspectjweaver/1.9.7/aspectjweaver-1.9.7.jar
* 这里需要把jar包的初始路径换成自己的maven仓库的地址
* 这个参数一加，就可以在类记载阶段，把原始的class字节码文件做一个增强改动。、
* 加上之后，就可以增强了，也就是在类加载阶段对class字节码进行改写和增强
* 这个例子也演示了：如果在需要增强的目标方法内里面，一个方法调用了另外一个方法，那么内部的方法调用是不会走
* 代理增强的，因为是通过this去调用的，不是走的代理，是直接调用。但是我们这个例子加上参数之后，是增强了，即时
* 没有走代理，也没有关系，因为这里不是通过代理类来增强的字节码，而是直接修改了myservice的字节码
* 只不过是在类加载阶段来修改的
* */

/*
* 注意几点
    1. 版本选择了 java 8, 因为目前的 aspectj-maven-plugin 1.14.0 最高只支持到 java 16
    2. 运行时需要在 VM options 里加入 -javaagent:C:/Users/manyh/.m2/repository/org/aspectj/aspectjweaver/1.9.7/aspectjweaver-1.9.7.jar
        把其中 C:/Users/manyh/.m2/repository 改为你自己 maven 仓库起始地址
* */
@SpringBootApplication
public class A10 {

    private static final Logger log = LoggerFactory.getLogger(A10.class);

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(A10.class, args);
        MyService service = context.getBean(MyService.class);

        // MyService 并非代理, 但 foo 方法也被增强了, 做增强的 java agent, 在加载类时, 修改了 class 字节码
        log.debug("service class: {}", service.getClass());
        service.foo();

//        context.close();

        /*
        * aop 的原理并非代理一种, agent 也能, 只要字节码变了, 行为就变了
        * */
    }
}
